package com.casic.ops.service.impl.pipeline;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.ops.dao.pipeline.PipelineDAO;
import com.casic.ops.dao.pipeline.PipelineLoggerDAO;
import com.casic.ops.entity.domain.pipeline.PipelineDO;
import com.casic.ops.entity.domain.pipeline.PipelineLoggerDO;
import com.casic.ops.entity.dto.pipeline.PipelineDTO;
import com.casic.ops.entity.dto.pipeline.datastructure.graph.Endpoints;
import com.casic.ops.entity.dto.pipeline.datastructure.graph.Graph;
import com.casic.ops.entity.dto.pipeline.datastructure.graph.Nodes;
import com.casic.ops.entity.request.pipeline.PipelinePageRequest;
import com.casic.ops.entity.request.pipeline.PipelineRequest;
import com.casic.ops.entity.vo.DashBordRecentPipeline;
import com.casic.ops.entity.vo.pipeline.PipelineBuildHistoryVO;
import com.casic.ops.entity.vo.pipeline.RecentPipelineVO;
import com.casic.ops.entity.vo.pipeline.response.MultiResponse;
import com.casic.ops.entity.vo.pipeline.response.PageResponse;
import com.casic.ops.entity.vo.pipeline.response.Response;
import com.casic.ops.entity.vo.pipeline.response.SingleResponse;
import com.casic.ops.handler.pipeline.PipelineExecutor;
import com.casic.ops.service.api.pipeline.PipelineLoggerService;
import com.casic.ops.service.api.pipeline.PipelineService;
import com.casic.ops.utils.OpsSnowFlake;
import com.casic.ops.utils.pipeline.PipelineConvertor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class PipelineServiceImpl implements PipelineService {

    @Resource
    private PipelineDAO pipelineDAO;

    @Resource
    private PipelineLoggerDAO pipelineLoggerDAO;

    @Resource
    private PipelineConvertor pipelineConvertor;

    @Resource
    private PipelineExecutor pipelineExecutor;

    @Override
    public Response add(PipelineRequest pipelineRequest) {
        PipelineDTO pipelineDTO=pipelineRequest.getPipelineDTO();
        pipelineDTO.validate();
        pipelineDTO.init();
        PipelineDO pipelineDO=pipelineConvertor.toDO(pipelineDTO);
        pipelineDO.setUuid(OpsSnowFlake.getInstance().nextId());
        System.out.println(pipelineDO.getId());
        int result=pipelineDAO.insert(pipelineDO);
        if (result==0){
            return Response.error("新增流水线失败");
        }else {
            QueryWrapper<PipelineDO> qw=new QueryWrapper<>();
            qw.eq("uuid",pipelineDO.getUuid());
            PipelineDO pipelineDO2=pipelineDAO.selectOne(qw);
            System.out.println(pipelineDO2.getId());
            return SingleResponse.of(pipelineDO2.getId());
        }
    }

    @Override
    public Response update(PipelineRequest pipelineRequest) {
        UpdateWrapper<PipelineDO> updateWrapper=new UpdateWrapper<>();
        PipelineDTO pipelineDTO=pipelineRequest.getPipelineDTO();
        updateWrapper.eq("id",pipelineDTO.getId());
        updateWrapper.set("description",pipelineDTO.getDescription());
        updateWrapper.set("application_uuid",pipelineDTO.getApplicationUuid());
        String pipelineContext=JSON.toJSONString(pipelineDTO.getGraph());
        updateWrapper.set("pipeline_context",pipelineContext);
        updateWrapper.set("pipeline_name",pipelineDTO.getPipelineName());
        updateWrapper.set("trigger_way",pipelineDTO.getTriggerWay());
        int result=pipelineDAO.update(null,updateWrapper);
        if (result==0){
            return Response.error("更新流水线失败");
        }else{
            return Response.success("更新成功");
        }
    }

    @Override
    public Response delete(Long id) {
        /**
         * 此处的删除为逻辑删除，对应deleted字段，0为删除，1为未删除
         */
            PipelineDO pipelineDO=pipelineDAO.selectById(id);
            if(pipelineDO!=null){
                UpdateWrapper<PipelineDO> uw=new UpdateWrapper<>();
                uw.eq("id",id);
                uw.set("deleted",0);
                pipelineDAO.update(null,uw);
            }
        return Response.success();
    }

    @Override
    public Response batchDelete(Long[] ids) {
        /**
         * 此处的删除为逻辑删除，对应deleted字段，0为删除，1为未删除
         */
        for(Long id:ids){
            PipelineDO pipelineDO=pipelineDAO.selectById(id);
            if(pipelineDO!=null){
                UpdateWrapper<PipelineDO> uw=new UpdateWrapper<>();
                uw.eq("id",id);
                uw.set("deleted",0);
                pipelineDAO.update(null,uw);
            }
        }
        return Response.success();
    }

    @Override
    public SingleResponse<PipelineDTO> getById(Long id) {
        PipelineDO pipelineDO=pipelineDAO.selectById(id);
        if (pipelineDO==null){
            PipelineDTO pipelineDTO=new PipelineDTO();
            Graph graph=new Graph();
            graph.setNodes(new ArrayList<Nodes>()).setEndpoints(new ArrayList<Endpoints>()).setEdges(new ArrayList<String>()).setHead("");
            String pipelineContext=JSON.toJSONString(graph);
            //String pipelineContext="{\"edges\":null,\"endpoints\":null,\"head\":null,\"nodes\":null}";
            pipelineDTO.setApplicationUuid(null).setDescription(null).setGraph(graph).setPipelineContext(pipelineContext).setPipelineName(null).setTriggerWay(null);
            return SingleResponse.of(pipelineDTO);
        }else {
            return SingleResponse.of(pipelineConvertor.toDTO(pipelineDO));
        }
    }

    @Override
    public MultiResponse<PipelineDTO> list() {
        QueryWrapper<PipelineDO> qw=new QueryWrapper<>();
        List<PipelineDO> pipelineDOList=pipelineDAO.selectList(qw);
        List<PipelineDTO> pipelineDTOList=pipelineConvertor.toDTOList(pipelineDOList);
        return MultiResponse.of(pipelineDTOList);
    }

    @Override
    public PageResponse<PipelineDTO> page(PipelinePageRequest pipelinePageRequest) {
        QueryWrapper<PipelineDO> qw=new QueryWrapper();
        qw.eq("deleted","1");
        qw.orderBy(true,false,"gmt_create");
        /**
         * 查询总数并保存总数
         */
        Integer count=pipelineDAO.selectCount(qw);
        PageResponse<PipelineDTO> response=new PageResponse<>();
        response.setTotalCount(count);
        response.setPageIndex(pipelinePageRequest.getPageIndex());
        response.setPageSize(pipelinePageRequest.getPageSize());
        /**
         * 获取一个Page数据，并保存返回
         */
        Page<PipelineDO> page=new Page<>(pipelinePageRequest.getPageIndex(), pipelinePageRequest.getPageSize());
        IPage<PipelineDO> iPage=pipelineDAO.selectPage(page,qw);
        List<PipelineDO> records=iPage.getRecords();
        List<PipelineDTO> pipelineDTOList=pipelineConvertor.toDTOList(records);
        response.setData(pipelineDTOList);
        return response;
    }

    @Override
    public PipelineDO selectById(long id) {
        PipelineDO pipelineDO=pipelineDAO.selectById(id);
        return pipelineDO;
    }

    @Override
    public Response deploy(Long id) {
        /**
         *原生的就这样，应该还没写逻辑
         */
        return Response.success();
    }

    @Override
    public Response execute(Long id) {
        if(id==0){
            return Response.error(404,"请先保存流水线");
        }else {
            return pipelineExecutor.execute(id);
        }
    }

    @Override
    public Response getRecentlyPipeline() {
        /**
         * 首页，先获取最新的4个最新执行记录
         */
        QueryWrapper<PipelineDO> qw=new QueryWrapper<>();
        qw.orderByDesc("gmt_create");
        qw.last("LIMIT 4");
        List<PipelineDO> pipelineDOList=pipelineDAO.selectList(qw);
        List<RecentPipelineVO> recentPipelineVOList =new ArrayList<>();
        for(PipelineDO pipelineDO:pipelineDOList) {
            //查询最新的一条执行记录
            QueryWrapper<PipelineLoggerDO> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("pipeline_uuid",pipelineDO.getUuid());
            queryWrapper.orderByDesc("execute_start_time");
            queryWrapper.last("LIMIT 1");
            PipelineLoggerDO pipelineLoggerDO=pipelineLoggerDAO.selectOne(queryWrapper);
            RecentPipelineVO vo=new RecentPipelineVO();
            if(pipelineLoggerDO!=null){
            vo.setRecentTime(pipelineLoggerDO.getExecuteStartTime());
            vo.setTrigger(pipelineLoggerDO.getCreator());
            }else {
                vo.setTrigger("暂未执行");
            }
            vo.setPipelineName(pipelineDO.getPipelineName());
            QueryWrapper<PipelineLoggerDO> wrapper=new QueryWrapper<>();
            wrapper.eq("pipeline_uuid",pipelineDO.getUuid());
            List<PipelineLoggerDO> pipelineLoggerDOList=pipelineLoggerDAO.selectList(wrapper);
            if(!pipelineLoggerDOList.isEmpty()) {
                long totalCount = pipelineLoggerDOList.stream().count();
                long successCount = pipelineLoggerDOList.stream().filter(s -> s.getFinalStatus().equals("成功")).count();
                vo.setTotalCount(totalCount);
                vo.setSuccessCount(successCount);
            }
            recentPipelineVOList.add(vo);
        }
        DashBordRecentPipeline dashBordRecentPipeline=new DashBordRecentPipeline();
        dashBordRecentPipeline.setRecentPipelineVOList(recentPipelineVOList);
        return SingleResponse.of(dashBordRecentPipeline);
    }
}
